package com.hxx.day11;

import com.hxx.day11.domain.Person;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 反射技术：动态创建对象的技术
 *  1. 反射技术可以在程序运行时，动态加载类、调用类的方法、访问类的属性等。
 *  2. 反射技术可以实现动态代理、动态加载类等功能。
 */
public class TestDemo {
    /**
     * 获取反射类型
     */
    @Test
    public void test1()throws Exception{
        // 1. 获取反射类型Class.forName("类的全路径")
        Class<?> clazz = Class.forName("com.hxx.day11.domain.Person");
        //创建对象
        // 2. 创建对象
        Person person = (Person) clazz.newInstance();
        System.out.println(person);
    }
    @Test
    public void test2()throws Exception{
        // 1. 获取反射类型
        Class<?> clazz = Person.class;
        //创建对象
        // 2. 创建对象
        Person person = (Person) clazz.newInstance();
        System.out.println(person);
    }
    @Test
    public void test3()throws Exception{
        Person person1 = new Person();
        // 1. 获取反射类型:通过对象获取的
        Class<?> clazz = person1.getClass();
        //创建对象
        // 2. 创建对象
        Person person = (Person) clazz.newInstance();
        System.out.println(person);
    }

    @Test
    public void test4()throws Exception{
       //通过类加载器获取反射类型
        Class<?> clazz = new ClassLoader(){}
                .loadClass("com.hxx.day11.domain.Person");
        Person person = (Person) clazz.newInstance();
        System.out.println(person);
    }

    /**
     * 反编译器
     * @param args
     */
     public static void main(String[] args) {
         hxx(String.class);
     }
     public static void hxx(Class<?> aClass){
         StringBuilder sb = new StringBuilder();
         //获取反射类型         Class<Person> aClass = Person.class;
         //获取类的全路径
         String className = aClass.getName();
         sb.append("package ").append(className).append(";\n");
         //获取类的修饰符
         int modifiers = aClass.getModifiers();
         sb.append(Modifier.toString(modifiers));
         //判断
         if (!aClass.isInterface()){
             sb.append(" class ").append(aClass.getSimpleName()).append(" {\n\t");
         }
         //获取构造方法
         Constructor<?>[] constructors = aClass.getConstructors();
         for (Constructor<?> constructor : constructors) {
             //获取构造方法的修饰符
             int a = constructor.getModifiers();
             sb.append(Modifier.toString(a)).append(" ");
             sb.append(aClass.getSimpleName()).append("(");
             //判断构造方法的参数
             Class<?>[] parameterTypes = constructor.getParameterTypes();
             if (parameterTypes.length > 0) {
                 int i = 0;
                 for (Class<?> parameterType : parameterTypes) {
                     sb.append(parameterType.getSimpleName())
                             .append(" arg").append(i++).append(",");
                 }
                 sb.deleteCharAt(sb.length() - 1);
                 sb.append("){}\n\t");
             }else {
                 sb.append("){}\n\t");
             }
         }
         //获取属性
         Field[] fields = aClass.getDeclaredFields();
         for (Field field : fields) {
             //获取属性的修饰符
             int b = field.getModifiers();
             sb.append(Modifier.toString(b)).append(" ");
             //获取属性的类型
             sb.append(field.getType().getSimpleName()).append(" ");
             //获取属性的名称
             sb.append(field.getName()).append(";\n\t");
         }
         //获取方法
         Method[] methods = aClass.getDeclaredMethods();
         for (Method method : methods) {
             //获取修饰符
             sb.append(Modifier.toString(method.getModifiers())).append(" ");
             sb.append(method.getReturnType().getSimpleName()).append(" ");
             sb.append(method.getName()).append("(");
             //判断是否有参数
             Class<?>[] types = method.getParameterTypes();
             if (types.length > 0) {
                 int i = 0;
                 for (Class<?> type : types) {
                     sb.append(type.getSimpleName()).append(" arg").append(i++).append(",");
                 }
                 sb.deleteCharAt(sb.length() - 1);
                 sb.append("){}\n\t");
             }else {
                 sb.append("){}\n\t");
             }
         }
         sb.append("}\n");
         System.out.println(sb);
     }
}
























